package com.tianfei.crowd.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.tianfei.crowd.constant.AccessPassAndStaticResource;
import com.tianfei.crowd.constant.CrowdConstants;
import com.tianfei.crowd.entity.vo.MemberLoginVO;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Zuul 网关的过滤器
 * 用于过滤需要进行过滤的请求
 *
 * @author: Herz
 * @date: 2021/8/2 16:02
 */

@Component
public class CrowdAccessFilter extends ZuulFilter {
    @Override
    public String filterType() {

        // 这里返回“pre”，表示在目标微服务前执行过滤
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判断该请求是否要进行过滤
     *
     * @return true：要进行过滤，false反之
     */
    @Override
    public boolean shouldFilter() {

        // 1、获取 requestContext 对象
        RequestContext requestContext = RequestContext.getCurrentContext();

        // 2、获取当前 request 对象
        HttpServletRequest request = requestContext.getRequest();

        // 3、获取请求地址
        String servletPath = request.getServletPath();

        // 4、判断当前请求是否是不需要过滤的特定请求
        boolean resultPass = AccessPassAndStaticResource.PASS_RES_SET.contains(servletPath);

        // 5、是特定的请求
        if (resultPass == true) {
            return false;
        }

        // 6、判断当前请求是否是不过滤的访问静态资源请求
        boolean staticResource = AccessPassAndStaticResource.judgeCurrentServletPathWhetherStaticResource(servletPath);

        // 7、是访问静态资源的请求
        if (staticResource == true) {
            return false;
        }

        // 8、如果都不是，则需要进行过滤
        return true;
    }

    /**
     * 过滤的具体操作
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {

        // 1、获取当前 request 对象
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        // 2、获取 Session 对象
        HttpSession session = request.getSession();

        // 3、尝试获取 Session 域 中 的已经登录的用户
        MemberLoginVO loginMember = (MemberLoginVO) session.getAttribute(CrowdConstants.MESSAGE_ATTR_MEMBER);

        // 4、如果 loginMember 为空 即 未登录
        if (loginMember == null) {

            // 5、从 requestContext 对象中获取 response 对象
            HttpServletResponse response = requestContext.getResponse();

            // 6、将提示消息存入 session 域中
            session.setAttribute(CrowdConstants.ATTR_NAME_MESSAGE, CrowdConstants.MESSAGE_ACCESS_FORBIDDEN);

            // 7、重定向到 crowdfunding12-member-authentication-consumer 工程 的登录页面
            try {
                response.sendRedirect("/auth/member/to/login/page");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        // 如果登录，则执行后续其他操作


        return null;
    }
}
